package top.revery.api.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.springframework.util.StringUtils;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * <h1> --- 创瑞云短信接口 --- </h1>
 * Created by  revery.top jun
 * Date  2019-12-03 09:57
 *
 * 调用示例：
 *  SendMessage sendMessage = new SendMessage();
 *  sendMessage.send("18575005397","998712","2马路", SMS_TemplateI.VERIFICATION_CODE);
 */
public class SendMessage {

    /*
     * 发送接口
     * */
    private final String url = "https://api.1cloudsp.com/api/v2/single_send";

    /*
     * 短信密钥
     * */
    private final String accessKey = "18575005397";
    private final String secret = "6EB944BEF61388E4F9611BB20FEE";

    public String send(String tel,String sign, SMS_TemplateI templateID) throws Exception{
        //验证手机号
        if(!reveryTool.isTel(tel)){
            throw new Exception("手机号码不正确！");
        }

        String code = creatCode();
        String codeSign = getSignFromCode(code,tel);

        Map<String,String> data = new HashMap<String, String>();
        data.put("accesskey",accessKey);
        data.put("secret",secret);
        data.put("mobile",tel);
        data.put("content",code);
        data.put("sign","【"+sign+"】");
        data.put("templateId",templateID.getCode());

        JSONObject json = reveryTool.http(url,data);
        if(json==null) {
            throw new Exception("发送失败，未知原因");
        }else if(!json.getString("code").equals("0")){
            throw new Exception("短信发送失败，错误原因："+json.getString("msg"));
        }

        return codeSign;
    }



    /*
     * 验证密钥是否正确
     *
     * */
    public boolean checkCodeSign(String code,String tel,String sign){
        if(StringUtils.isEmpty(code) || StringUtils.isEmpty(sign)){
            return false;
        }

        //解密sign
        try {
            byte[] raw = encryptKey.getBytes("utf-8");
            SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            cipher.init(Cipher.DECRYPT_MODE, skeySpec);

            Base64.Decoder decoder = Base64.getDecoder();
            byte[] encrypted1 = decoder.decode(sign);
            byte[] original = cipher.doFinal(encrypted1);
            String originalString = new String(original,"utf-8");

            JSONObject jsonObject = JSON.parseObject(originalString);

            //验证code和手机号是否匹配
            if(!jsonObject.getString("code").equals(code) || !jsonObject.getString("tel").equals(tel)){
                throw new Exception("验证码不匹配！");
            }

            //验证失效
            int invalidTime = 10*60*1000; //失效时间，10分钟
            Long time1 = jsonObject.getLong("time");
            Long time2 = new Date().getTime();
            if(time2>(time1+invalidTime)){
                throw new Exception("验证码已失效！");
            }

            return true;

        } catch (Exception e) {
            System.out.println(e.getMessage());
        }

        return false;
    }

    /*
     * 根据随机数生成密钥
     * */
    private final String encryptKey = "Z%5123**XRWz*E%$$&&%2312fAF#@ZR^"; //AES密钥
    private String getSignFromCode(String code,String tel) throws Exception {
        //需要加密的内容
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("code",code);
        jsonObject.put("tel",tel);
        jsonObject.put("time",new Date().getTime());
        byte[] data = jsonObject.toJSONString().getBytes("utf-8");

        //AES加密
        byte[] raw = encryptKey.getBytes("utf-8");
        SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");//"算法/模式/补码方式"
        cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
        byte[] encrypted = cipher.doFinal(data);

        //返回base64
        Base64.Encoder encode = Base64.getEncoder();
        return encode.encodeToString(encrypted);
    }

    /*
     * 生成随机验证码
     *   返回加密密钥
     * */
    private String creatCode(){
        String randomStr = String.valueOf(Math.random());
        return randomStr.substring(2,8);
    }



    /*
     * 短信模板类型
     * */
    @Getter
    @AllArgsConstructor
    public enum SMS_TemplateI {
        VERIFICATION_CODE("验证码模板","142711");
        /*
         * 描述
         * */
        private String description;

        /*
         * ID码
         * */
        private String code;
    }
}
